"use client";

import React, { useMemo } from "react";
import { Input } from "../ui/input";
import { Button } from "../ui/button";
import { type VariantProps } from "class-variance-authority";
// import { CommandInput } from '../ui/command';
import { TagPopover } from "./tag-popover";
import { TagList } from "./tag-list";
import { tagVariants } from "./tag";
import { Autocomplete } from "./autocomplete";
import { cn } from "@app/lib/cn";
import { useTranslations } from "next-intl";

export enum Delimiter {
    Comma = ",",
    Enter = "Enter"
}

type OmittedInputProps = Omit<
    React.InputHTMLAttributes<HTMLInputElement>,
    "size" | "value"
>;

export type Tag = {
    id: string;
    text: string;
};

export interface TagInputStyleClassesProps {
    inlineTagsContainer?: string;
    tagPopover?: {
        popoverTrigger?: string;
        popoverContent?: string;
    };
    tagList?: {
        container?: string;
        sortableList?: string;
    };
    autoComplete?: {
        command?: string;
        popoverTrigger?: string;
        popoverContent?: string;
        commandList?: string;
        commandGroup?: string;
        commandItem?: string;
    };
    tag?: {
        body?: string;
        closeButton?: string;
    };
    input?: string;
    clearAllButton?: string;
}

export interface TagInputProps
    extends OmittedInputProps,
        VariantProps<typeof tagVariants> {
    placeholder?: string;
    tags: Tag[];
    setTags: React.Dispatch<React.SetStateAction<Tag[]>>;
    enableAutocomplete?: boolean;
    autocompleteOptions?: Tag[];
    maxTags?: number;
    minTags?: number;
    readOnly?: boolean;
    disabled?: boolean;
    onTagAdd?: (tag: string) => void;
    onTagRemove?: (tag: string) => void;
    allowDuplicates?: boolean;
    validateTag?: (tag: string) => boolean;
    delimiter?: Delimiter;
    showCount?: boolean;
    placeholderWhenFull?: string;
    sortTags?: boolean;
    delimiterList?: string[];
    truncate?: number;
    minLength?: number;
    maxLength?: number;
    usePopoverForTags?: boolean;
    value?:
        | string
        | number
        | readonly string[]
        | { id: string; text: string }[];
    autocompleteFilter?: (option: string) => boolean;
    direction?: "row" | "column";
    onInputChange?: (value: string) => void;
    customTagRenderer?: (tag: Tag, isActiveTag: boolean) => React.ReactNode;
    onFocus?: React.FocusEventHandler<HTMLInputElement>;
    onBlur?: React.FocusEventHandler<HTMLInputElement>;
    onTagClick?: (tag: Tag) => void;
    draggable?: boolean;
    inputFieldPosition?: "bottom" | "top";
    clearAll?: boolean;
    onClearAll?: () => void;
    inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
    restrictTagsToAutocompleteOptions?: boolean;
    inlineTags?: boolean;
    activeTagIndex: number | null;
    setActiveTagIndex: React.Dispatch<React.SetStateAction<number | null>>;
    styleClasses?: TagInputStyleClassesProps;
    usePortal?: boolean;
    addOnPaste?: boolean;
    addTagsOnBlur?: boolean;
    generateTagId?: () => string;
}

const TagInput = React.forwardRef<HTMLInputElement, TagInputProps>(
    (props, ref) => {
        const {
            id,
            placeholder,
            tags,
            setTags,
            variant,
            size,
            shape,
            enableAutocomplete,
            autocompleteOptions,
            maxTags,
            delimiter = Delimiter.Comma,
            onTagAdd,
            onTagRemove,
            allowDuplicates,
            showCount,
            validateTag,
            placeholderWhenFull = "Max tags reached",
            sortTags,
            delimiterList,
            truncate,
            autocompleteFilter,
            borderStyle,
            textCase,
            interaction,
            animation,
            textStyle,
            minLength,
            maxLength,
            direction = "row",
            onInputChange,
            customTagRenderer,
            onFocus,
            onBlur,
            onTagClick,
            draggable = false,
            inputFieldPosition = "bottom",
            clearAll = false,
            onClearAll,
            usePopoverForTags = false,
            inputProps = {},
            restrictTagsToAutocompleteOptions,
            inlineTags = true,
            addTagsOnBlur = false,
            activeTagIndex,
            setActiveTagIndex,
            styleClasses = {},
            disabled = false,
            usePortal = false,
            addOnPaste = false,
            generateTagId = uuid
        } = props;

        const [inputValue, setInputValue] = React.useState("");
        const [tagCount, setTagCount] = React.useState(
            Math.max(0, tags.length)
        );
        const inputRef = React.useRef<HTMLInputElement>(null);

        const t = useTranslations();

        if (
            (maxTags !== undefined && maxTags < 0) ||
            (props.minTags !== undefined && props.minTags < 0)
        ) {
            console.warn(t("tagsWarnCannotBeLessThanZero"));
            // error
            return null;
        }

        const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
            const newValue = e.target.value;
            if (addOnPaste && newValue.includes(delimiter)) {
                const splitValues = newValue
                    .split(delimiter)
                    .map((v) => v.trim())
                    .filter((v) => v);
                splitValues.forEach((value) => {
                    if (!value) return; // Skip empty strings from split

                    const newTagText = value.trim();

                    // Check if the tag is in the autocomplete options if restrictTagsToAutocomplete is true
                    if (
                        restrictTagsToAutocompleteOptions &&
                        !autocompleteOptions?.some(
                            (option) => option.text === newTagText
                        )
                    ) {
                        console.warn(
                            t("tagsWarnNotAllowedAutocompleteOptions")
                        );
                        return;
                    }

                    if (validateTag && !validateTag(newTagText)) {
                        console.warn(t("tagsWarnInvalid"));
                        return;
                    }

                    if (minLength && newTagText.length < minLength) {
                        console.warn(
                            t("tagWarnTooShort", { tagText: newTagText })
                        );
                        return;
                    }

                    if (maxLength && newTagText.length > maxLength) {
                        console.warn(
                            t("tagWarnTooLong", { tagText: newTagText })
                        );
                        return;
                    }

                    const newTagId = generateTagId();

                    // Add tag if duplicates are allowed or tag does not already exist
                    if (
                        allowDuplicates ||
                        !tags.some((tag) => tag.text === newTagText)
                    ) {
                        if (maxTags === undefined || tags.length < maxTags) {
                            // Check for maxTags limit
                            const newTag = { id: newTagId, text: newTagText };
                            setTags((prevTags) => [...prevTags, newTag]);
                            onTagAdd?.(newTagText);
                        } else {
                            console.warn(t("tagsWarnReachedMaxNumber"));
                        }
                    } else {
                        console.warn(
                            t("tagWarnDuplicate", { tagText: newTagText })
                        );
                    }
                });
                setInputValue("");
            } else {
                setInputValue(newValue);
            }
            onInputChange?.(newValue);
        };

        const handleInputFocus = (
            event: React.FocusEvent<HTMLInputElement>
        ) => {
            setActiveTagIndex(null); // Reset active tag index when the input field gains focus
            onFocus?.(event);
        };

        const handleInputBlur = (event: React.FocusEvent<HTMLInputElement>) => {
            if (addTagsOnBlur && inputValue.trim()) {
                const newTagText = inputValue.trim();

                if (validateTag && !validateTag(newTagText)) {
                    return;
                }

                if (minLength && newTagText.length < minLength) {
                    console.warn(t("tagWarnTooShort"));
                    return;
                }

                if (maxLength && newTagText.length > maxLength) {
                    console.warn(t("tagWarnTooLong"));
                    return;
                }

                if (
                    (allowDuplicates ||
                        !tags.some((tag) => tag.text === newTagText)) &&
                    (maxTags === undefined || tags.length < maxTags)
                ) {
                    const newTagId = generateTagId();
                    setTags([...tags, { id: newTagId, text: newTagText }]);
                    onTagAdd?.(newTagText);
                    setTagCount((prevTagCount) => prevTagCount + 1);
                    setInputValue("");
                }
            }

            onBlur?.(event);
        };

        const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
            if (
                delimiterList
                    ? delimiterList.includes(e.key)
                    : e.key === delimiter || e.key === Delimiter.Enter
            ) {
                e.preventDefault();
                const newTagText = inputValue.trim();

                // Check if the tag is in the autocomplete options if restrictTagsToAutocomplete is true
                if (
                    restrictTagsToAutocompleteOptions &&
                    !autocompleteOptions?.some(
                        (option) => option.text === newTagText
                    )
                ) {
                    // error
                    return;
                }

                if (validateTag && !validateTag(newTagText)) {
                    return;
                }

                if (minLength && newTagText.length < minLength) {
                    console.warn(t("tagWarnTooShort"));
                    // error
                    return;
                }

                // Validate maxLength
                if (maxLength && newTagText.length > maxLength) {
                    // error
                    console.warn(t("tagWarnTooLong"));
                    return;
                }

                const newTagId = generateTagId();

                if (
                    newTagText &&
                    (allowDuplicates ||
                        !tags.some((tag) => tag.text === newTagText)) &&
                    (maxTags === undefined || tags.length < maxTags)
                ) {
                    setTags([...tags, { id: newTagId, text: newTagText }]);
                    onTagAdd?.(newTagText);
                    setTagCount((prevTagCount) => prevTagCount + 1);
                }
                setInputValue("");
            } else {
                switch (e.key) {
                    case "Delete":
                        if (activeTagIndex !== null) {
                            e.preventDefault();
                            const newTags = [...tags];
                            newTags.splice(activeTagIndex, 1);
                            setTags(newTags);
                            setActiveTagIndex((prev) =>
                                newTags.length === 0
                                    ? null
                                    : prev! >= newTags.length
                                      ? newTags.length - 1
                                      : prev
                            );
                            setTagCount((prevTagCount) => prevTagCount - 1);
                            onTagRemove?.(tags[activeTagIndex].text);
                        }
                        break;
                    case "Backspace":
                        if (activeTagIndex !== null) {
                            e.preventDefault();
                            const newTags = [...tags];
                            newTags.splice(activeTagIndex, 1);
                            setTags(newTags);
                            setActiveTagIndex((prev) =>
                                prev! === 0 ? null : prev! - 1
                            );
                            setTagCount((prevTagCount) => prevTagCount - 1);
                            onTagRemove?.(tags[activeTagIndex].text);
                        }
                        break;
                    case "ArrowRight":
                        e.preventDefault();
                        if (activeTagIndex === null) {
                            setActiveTagIndex(0);
                        } else {
                            setActiveTagIndex((prev) =>
                                prev! + 1 >= tags.length ? 0 : prev! + 1
                            );
                        }
                        break;
                    case "ArrowLeft":
                        e.preventDefault();
                        if (activeTagIndex === null) {
                            setActiveTagIndex(tags.length - 1);
                        } else {
                            setActiveTagIndex((prev) =>
                                prev! === 0 ? tags.length - 1 : prev! - 1
                            );
                        }
                        break;
                    case "Home":
                        e.preventDefault();
                        setActiveTagIndex(0);
                        break;
                    case "End":
                        e.preventDefault();
                        setActiveTagIndex(tags.length - 1);
                        break;
                }
            }
        };

        const removeTag = (idToRemove: string) => {
            setTags(tags.filter((tag) => tag.id !== idToRemove));
            onTagRemove?.(
                tags.find((tag) => tag.id === idToRemove)?.text || ""
            );
            setTagCount((prevTagCount) => prevTagCount - 1);
        };

        const onSortEnd = (oldIndex: number, newIndex: number) => {
            setTags((currentTags) => {
                const newTags = [...currentTags];
                const [removedTag] = newTags.splice(oldIndex, 1);
                newTags.splice(newIndex, 0, removedTag);

                return newTags;
            });
        };

        const handleClearAll = () => {
            if (!onClearAll) {
                setActiveTagIndex(-1);
                setTags([]);
                return;
            }
            onClearAll?.();
        };

        // const filteredAutocompleteOptions = autocompleteFilter
        //   ? autocompleteOptions?.filter((option) => autocompleteFilter(option.text))
        //   : autocompleteOptions;
        const filteredAutocompleteOptions = useMemo(() => {
            return (autocompleteOptions || []).filter((option) =>
                option.text
                    .toLowerCase()
                    .includes(inputValue ? inputValue.toLowerCase() : "")
            );
        }, [inputValue, autocompleteOptions]);

        const displayedTags = sortTags ? [...tags].sort() : tags;

        const truncatedTags = truncate
            ? tags.map((tag) => ({
                  id: tag.id,
                  text:
                      tag.text?.length > truncate
                          ? `${tag.text.substring(0, truncate)}...`
                          : tag.text
              }))
            : displayedTags;

        return (
            <div
                className={`w-full flex ${!inlineTags && tags.length > 0 ? "gap-3" : ""} ${
                    inputFieldPosition === "bottom"
                        ? "flex-col"
                        : inputFieldPosition === "top"
                          ? "flex-col-reverse"
                          : "flex-row"
                }`}
            >
                {!usePopoverForTags &&
                    (!inlineTags ? (
                        <TagList
                            tags={truncatedTags}
                            customTagRenderer={customTagRenderer}
                            variant={variant}
                            size={size}
                            shape={shape}
                            borderStyle={borderStyle}
                            textCase={textCase}
                            interaction={interaction}
                            animation={animation}
                            textStyle={textStyle}
                            onTagClick={onTagClick}
                            draggable={draggable}
                            onSortEnd={onSortEnd}
                            onRemoveTag={removeTag}
                            direction={direction}
                            inlineTags={inlineTags}
                            activeTagIndex={activeTagIndex}
                            setActiveTagIndex={setActiveTagIndex}
                            classStyleProps={{
                                tagListClasses: styleClasses?.tagList,
                                tagClasses: styleClasses?.tag
                            }}
                            disabled={disabled}
                        />
                    ) : (
                        !enableAutocomplete && (
                            <div className="w-full">
                                <div
                                    className={cn(
                                        `flex flex-row flex-wrap items-center gap-1.5 p-1.5 w-full rounded-md border border-input text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50`,
                                        styleClasses?.inlineTagsContainer
                                    )}
                                >
                                    <TagList
                                        tags={truncatedTags}
                                        customTagRenderer={customTagRenderer}
                                        variant={variant}
                                        size={size}
                                        shape={shape}
                                        borderStyle={borderStyle}
                                        textCase={textCase}
                                        interaction={interaction}
                                        animation={animation}
                                        textStyle={textStyle}
                                        onTagClick={onTagClick}
                                        draggable={draggable}
                                        onSortEnd={onSortEnd}
                                        onRemoveTag={removeTag}
                                        direction={direction}
                                        inlineTags={inlineTags}
                                        activeTagIndex={activeTagIndex}
                                        setActiveTagIndex={setActiveTagIndex}
                                        classStyleProps={{
                                            tagListClasses:
                                                styleClasses?.tagList,
                                            tagClasses: styleClasses?.tag
                                        }}
                                        disabled={disabled}
                                    />
                                    <Input
                                        ref={inputRef}
                                        id={id}
                                        type="text"
                                        placeholder={
                                            maxTags !== undefined &&
                                            tags.length >= maxTags
                                                ? placeholderWhenFull
                                                : placeholder
                                        }
                                        value={inputValue}
                                        onChange={handleInputChange}
                                        onKeyDown={handleKeyDown}
                                        onFocus={handleInputFocus}
                                        onBlur={handleInputBlur}
                                        {...inputProps}
                                        className={cn(
                                            "border-0 h-5 bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 flex-1 w-fit shadow-none inset-shadow-none",
                                            // className,
                                            styleClasses?.input
                                        )}
                                        autoComplete={
                                            enableAutocomplete ? "on" : "off"
                                        }
                                        list={
                                            enableAutocomplete
                                                ? "autocomplete-options"
                                                : undefined
                                        }
                                        disabled={
                                            disabled ||
                                            (maxTags !== undefined &&
                                                tags.length >= maxTags)
                                        }
                                    />
                                </div>
                            </div>
                        )
                    ))}
                {enableAutocomplete ? (
                    <div className="w-full">
                        <Autocomplete
                            tags={tags}
                            setTags={setTags}
                            setInputValue={setInputValue}
                            autocompleteOptions={
                                filteredAutocompleteOptions as Tag[]
                            }
                            setTagCount={setTagCount}
                            maxTags={maxTags}
                            onTagAdd={onTagAdd}
                            onTagRemove={onTagRemove}
                            allowDuplicates={allowDuplicates ?? false}
                            inlineTags={inlineTags}
                            usePortal={usePortal}
                            classStyleProps={{
                                command: styleClasses?.autoComplete?.command,
                                popoverTrigger:
                                    styleClasses?.autoComplete?.popoverTrigger,
                                popoverContent:
                                    styleClasses?.autoComplete?.popoverContent,
                                commandList:
                                    styleClasses?.autoComplete?.commandList,
                                commandGroup:
                                    styleClasses?.autoComplete?.commandGroup,
                                commandItem:
                                    styleClasses?.autoComplete?.commandItem
                            }}
                        >
                            {!usePopoverForTags ? (
                                !inlineTags ? (
                                    // <CommandInput
                                    //   placeholder={maxTags !== undefined && tags.length >= maxTags ? placeholderWhenFull : placeholder}
                                    //   ref={inputRef}
                                    //   value={inputValue}
                                    //   disabled={disabled || (maxTags !== undefined && tags.length >= maxTags)}
                                    //   onChangeCapture={handleInputChange}
                                    //   onKeyDown={handleKeyDown}
                                    //   onFocus={handleInputFocus}
                                    //   onBlur={handleInputBlur}
                                    //   className={cn(
                                    //     'w-full',
                                    //     // className,
                                    //     styleClasses?.input,
                                    //   )}
                                    // />
                                    <Input
                                        ref={inputRef}
                                        id={id}
                                        type="text"
                                        placeholder={
                                            maxTags !== undefined &&
                                            tags.length >= maxTags
                                                ? placeholderWhenFull
                                                : placeholder
                                        }
                                        value={inputValue}
                                        onChange={handleInputChange}
                                        onKeyDown={handleKeyDown}
                                        onFocus={handleInputFocus}
                                        onBlur={handleInputBlur}
                                        {...inputProps}
                                        className={cn(
                                            "border-0 h-5 bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 flex-1 w-fit shadow-none inset-shadow-none",
                                            // className,
                                            styleClasses?.input
                                        )}
                                        autoComplete={
                                            enableAutocomplete ? "on" : "off"
                                        }
                                        list={
                                            enableAutocomplete
                                                ? "autocomplete-options"
                                                : undefined
                                        }
                                        disabled={
                                            disabled ||
                                            (maxTags !== undefined &&
                                                tags.length >= maxTags)
                                        }
                                    />
                                ) : (
                                    <div
                                        className={cn(
                                            `flex flex-row flex-wrap items-center p-1.5 gap-1.5 h-fit w-full bg-transparent text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:cursor-not-allowed disabled:opacity-50`,
                                            styleClasses?.inlineTagsContainer
                                        )}
                                    >
                                        <TagList
                                            tags={truncatedTags}
                                            customTagRenderer={
                                                customTagRenderer
                                            }
                                            variant={variant}
                                            size={size}
                                            shape={shape}
                                            borderStyle={borderStyle}
                                            textCase={textCase}
                                            interaction={interaction}
                                            animation={animation}
                                            textStyle={textStyle}
                                            onTagClick={onTagClick}
                                            draggable={draggable}
                                            onSortEnd={onSortEnd}
                                            onRemoveTag={removeTag}
                                            direction={direction}
                                            inlineTags={inlineTags}
                                            activeTagIndex={activeTagIndex}
                                            setActiveTagIndex={
                                                setActiveTagIndex
                                            }
                                            classStyleProps={{
                                                tagListClasses:
                                                    styleClasses?.tagList,
                                                tagClasses: styleClasses?.tag
                                            }}
                                            disabled={disabled}
                                        />
                                        {/* <CommandInput
                    placeholder={maxTags !== undefined && tags.length >= maxTags ? placeholderWhenFull : placeholder}
                    ref={inputRef}
                    value={inputValue}
                    disabled={disabled || (maxTags !== undefined && tags.length >= maxTags)}
                    onChangeCapture={handleInputChange}
                    onKeyDown={handleKeyDown}
                    onFocus={handleInputFocus}
                    onBlur={handleInputBlur}
                    inlineTags={inlineTags}
                    className={cn(
                      'border-0 flex-1 w-fit h-5',
                      // className,
                      styleClasses?.input,
                    )}
                  /> */}
                                        <Input
                                            ref={inputRef}
                                            id={id}
                                            type="text"
                                            placeholder={
                                                maxTags !== undefined &&
                                                tags.length >= maxTags
                                                    ? placeholderWhenFull
                                                    : placeholder
                                            }
                                            value={inputValue}
                                            onChange={handleInputChange}
                                            onKeyDown={handleKeyDown}
                                            onFocus={handleInputFocus}
                                            onBlur={handleInputBlur}
                                            {...inputProps}
                                            className={cn(
                                                "border-0 h-5 bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 flex-1 w-fit shadow-none inset-shadow-none",
                                                // className,
                                                styleClasses?.input
                                            )}
                                            autoComplete={
                                                enableAutocomplete
                                                    ? "on"
                                                    : "off"
                                            }
                                            list={
                                                enableAutocomplete
                                                    ? "autocomplete-options"
                                                    : undefined
                                            }
                                            disabled={
                                                disabled ||
                                                (maxTags !== undefined &&
                                                    tags.length >= maxTags)
                                            }
                                        />
                                    </div>
                                )
                            ) : (
                                <TagPopover
                                    tags={truncatedTags}
                                    customTagRenderer={customTagRenderer}
                                    variant={variant}
                                    size={size}
                                    shape={shape}
                                    borderStyle={borderStyle}
                                    textCase={textCase}
                                    interaction={interaction}
                                    animation={animation}
                                    textStyle={textStyle}
                                    onTagClick={onTagClick}
                                    draggable={draggable}
                                    onSortEnd={onSortEnd}
                                    onRemoveTag={removeTag}
                                    direction={direction}
                                    activeTagIndex={activeTagIndex}
                                    setActiveTagIndex={setActiveTagIndex}
                                    classStyleProps={{
                                        popoverClasses:
                                            styleClasses?.tagPopover,
                                        tagListClasses: styleClasses?.tagList,
                                        tagClasses: styleClasses?.tag
                                    }}
                                    disabled={disabled}
                                >
                                    {/* <CommandInput
                  placeholder={maxTags !== undefined && tags.length >= maxTags ? placeholderWhenFull : placeholder}
                  ref={inputRef}
                  value={inputValue}
                  disabled={disabled || (maxTags !== undefined && tags.length >= maxTags)}
                  onChangeCapture={handleInputChange}
                  onKeyDown={handleKeyDown}
                  onFocus={handleInputFocus}
                  onBlur={handleInputBlur}
                  className={cn(
                    'w-full',
                    // className,
                    styleClasses?.input,
                  )}
                /> */}
                                    <Input
                                        ref={inputRef}
                                        id={id}
                                        type="text"
                                        placeholder={
                                            maxTags !== undefined &&
                                            tags.length >= maxTags
                                                ? placeholderWhenFull
                                                : placeholder
                                        }
                                        value={inputValue}
                                        onChange={handleInputChange}
                                        onKeyDown={handleKeyDown}
                                        onFocus={handleInputFocus}
                                        onBlur={handleInputBlur}
                                        {...inputProps}
                                        className={cn(
                                            "border-0 h-5 bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 flex-1 w-fit shadow-none inset-shadow-none",
                                            // className,
                                            styleClasses?.input
                                        )}
                                        autoComplete={
                                            enableAutocomplete ? "on" : "off"
                                        }
                                        list={
                                            enableAutocomplete
                                                ? "autocomplete-options"
                                                : undefined
                                        }
                                        disabled={
                                            disabled ||
                                            (maxTags !== undefined &&
                                                tags.length >= maxTags)
                                        }
                                    />
                                </TagPopover>
                            )}
                        </Autocomplete>
                    </div>
                ) : (
                    <div className="w-full">
                        {!usePopoverForTags ? (
                            !inlineTags ? (
                                <Input
                                    ref={inputRef}
                                    id={id}
                                    type="text"
                                    placeholder={
                                        maxTags !== undefined &&
                                        tags.length >= maxTags
                                            ? placeholderWhenFull
                                            : placeholder
                                    }
                                    value={inputValue}
                                    onChange={handleInputChange}
                                    onKeyDown={handleKeyDown}
                                    onFocus={handleInputFocus}
                                    onBlur={handleInputBlur}
                                    {...inputProps}
                                    className={cn(
                                        styleClasses?.input,
                                        "shadow-none inset-shadow-none"
                                        // className
                                    )}
                                    autoComplete={
                                        enableAutocomplete ? "on" : "off"
                                    }
                                    list={
                                        enableAutocomplete
                                            ? "autocomplete-options"
                                            : undefined
                                    }
                                    disabled={
                                        disabled ||
                                        (maxTags !== undefined &&
                                            tags.length >= maxTags)
                                    }
                                />
                            ) : null
                        ) : (
                            <TagPopover
                                tags={truncatedTags}
                                customTagRenderer={customTagRenderer}
                                variant={variant}
                                size={size}
                                shape={shape}
                                borderStyle={borderStyle}
                                textCase={textCase}
                                interaction={interaction}
                                animation={animation}
                                textStyle={textStyle}
                                onTagClick={onTagClick}
                                draggable={draggable}
                                onSortEnd={onSortEnd}
                                onRemoveTag={removeTag}
                                direction={direction}
                                activeTagIndex={activeTagIndex}
                                setActiveTagIndex={setActiveTagIndex}
                                classStyleProps={{
                                    popoverClasses: styleClasses?.tagPopover,
                                    tagListClasses: styleClasses?.tagList,
                                    tagClasses: styleClasses?.tag
                                }}
                                disabled={disabled}
                            >
                                <Input
                                    ref={inputRef}
                                    id={id}
                                    type="text"
                                    placeholder={
                                        maxTags !== undefined &&
                                        tags.length >= maxTags
                                            ? placeholderWhenFull
                                            : placeholder
                                    }
                                    value={inputValue}
                                    onChange={handleInputChange}
                                    onKeyDown={handleKeyDown}
                                    onFocus={handleInputFocus}
                                    onBlur={handleInputBlur}
                                    {...inputProps}
                                    autoComplete={
                                        enableAutocomplete ? "on" : "off"
                                    }
                                    list={
                                        enableAutocomplete
                                            ? "autocomplete-options"
                                            : undefined
                                    }
                                    disabled={
                                        disabled ||
                                        (maxTags !== undefined &&
                                            tags.length >= maxTags)
                                    }
                                    className={cn(
                                        "border-0 w-full shadow-none inset-shadow-none",
                                        styleClasses?.input
                                        // className
                                    )}
                                />
                            </TagPopover>
                        )}
                    </div>
                )}

                {showCount && maxTags && (
                    <div className="flex">
                        <span className="text-muted-foreground text-sm mt-1 ml-auto">
                            {`${tagCount}`}/{`${maxTags}`}
                        </span>
                    </div>
                )}
                {clearAll && (
                    <Button
                        type="button"
                        onClick={handleClearAll}
                        className={cn("mt-2", styleClasses?.clearAllButton)}
                    >
                        Clear All
                    </Button>
                )}
            </div>
        );
    }
);

TagInput.displayName = "TagInput";

export function uuid() {
    return crypto.getRandomValues(new Uint32Array(1))[0].toString();
}

export { TagInput };
